﻿using Frame;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using VideoFileOrganization.BatchRename;

namespace VideoFileOrganization
{
    public class Global
    {
        private string HistoryPath;
        protected string m_appPath = System.Windows.Forms.Application.StartupPath + @"\PARAM\History.xml";
        //private string m_filePath; //处理文件目录
        //创建XML根节点对象
        XmlDocument xml;
        private XmlNode rootNode;
        private Dictionary<int, BaseFrm> m_frmDic;
        private Dictionary<int, RenameBaseFrm> m_renameFrmDic;
        private BatchRenameClass reName;
        public Global()
        {
            m_frmDic = new Dictionary<int, BaseFrm>();
            m_renameFrmDic = new Dictionary<int, RenameBaseFrm>();
            xml = new XmlDocument();
            LoadHistory();
            GetAllFrm();
            reName = new BatchRenameClass(xml);
        }

        public void LoadHistory()
        {
            xml.Load(m_appPath);
            rootNode = xml.SelectSingleNode("History");
            XmlNode pathNode = rootNode.SelectSingleNode("VideoFileOrganization").SelectSingleNode("Path");
            HistoryPath = pathNode.InnerText;
        }

        public void SaveHistory()
        {
            //xml = Frame.XmlFileHelper.LoadXml(m_appPath, "History");
            //XmlNode pathNode = Frame.XmlFileHelper.ScanChildElement(xml, rootNode.SelectSingleNode("VideoFileOrganization"), "Path", Path);
            rootNode.SelectSingleNode("VideoFileOrganization").SelectSingleNode("Path").InnerText = Path;
            reName.SaveHistory();
            xml.Save(m_appPath);
        }

        public BatchRenameClass BatchRename
        {
            get { return reName; }
        }

        public string Path
        {
            set { HistoryPath = value; }
            get { return HistoryPath; }
        }

        public Dictionary<int, BaseFrm> SubFormDic
        {
            set { m_frmDic = value; }
            get { return m_frmDic; }
        }

        public Dictionary<int, RenameBaseFrm> renameSubFormDic
        {
            set { m_renameFrmDic = value; }
            get { return m_renameFrmDic; }
        }

        public void GetAllFrm()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Type[] types = assembly.GetTypes();

            // 遍历所有类型，找出所有的 Form 类型
            foreach (Type type in types)
            {
                if (type.IsSubclassOf(typeof(BaseFrm)) && type != typeof(BaseFrm))
                {
                    BaseFrm frm = (BaseFrm)Activator.CreateInstance(type);                  
                    m_frmDic.Add(frm.Index, frm);
                }
                if (type.IsSubclassOf(typeof(RenameBaseFrm)) && type != typeof(RenameBaseFrm))
                {
                    RenameBaseFrm frm = (RenameBaseFrm)Activator.CreateInstance(type);
                    m_renameFrmDic.Add(frm.Index, frm);
                }
            }
        }

    }



    public class BatchRenameClass
    {
        public enum eReviseMode
        {
            BEFORE_A_RESERVED_CHARACTER = 0,            //保留字符前
            AFTER_A_RESERVED_CHARACTER,                 //保留字符后
            RETAIN_CHINESE,                             //保留中文
            RETAIN_ENGLISH,                             //保留英文 
            RETAIN_NUMBER,                              //保留数字
            REPLACE_THE_CHARACTERS,                     //将字符替换
        }
        public struct tReviseParam
        {
            public eReviseMode mode;
            public List<string> subString;
        }


        private List<string> m_Exes;
        private List<string> m_extensions;
        private List<string> m_IncludeCharacters;
        private List<string> m_FindAndReplaces;
        private XmlDocument xml;
        public BatchRenameClass(XmlDocument xml)
        {
            m_Exes = new List<string>();
            m_extensions = new List<string>();
            m_IncludeCharacters = new List<string>();
            m_FindAndReplaces = new List<string>();
            this.xml = xml;
            LoadHistory();
        }

        public List<string> Exes { get { return m_Exes; } }
        public List<string> Extensions
        {
            set { m_extensions = value; }
            get { return m_extensions; }
        }
        public List<string> IncludeCharacters
        {
            set { m_IncludeCharacters = value; }
            get { return m_IncludeCharacters; }
        }
        public List<string> FindAndReplaces
        {
            set { m_FindAndReplaces = value; }
            get { return m_FindAndReplaces; }
        }
        public void LoadHistory()
        {
            XmlNode DocumentCleanupNode = xml.SelectSingleNode("History").SelectSingleNode("VideoFileOrganization").SelectSingleNode("DocumentCleanup");
            XmlNodeList exetensionsNodes = DocumentCleanupNode.SelectSingleNode("extensions").ChildNodes;
            foreach(XmlNode node in exetensionsNodes)
            {
                if (node.Name == "value")
                    m_extensions.Add(node.InnerText);
            }
            XmlNodeList exesNodes = DocumentCleanupNode.SelectSingleNode("Exes").ChildNodes;
            foreach (XmlNode node in exesNodes)
            {
                if(node.Name == "value")
                    m_Exes.Add(node.InnerText);
            }
            XmlNodeList CharactersNodes = DocumentCleanupNode.SelectSingleNode("IncludeCharacters").ChildNodes;
            foreach (XmlNode node in CharactersNodes)
            {
                if (node.Name == "value")
                    m_IncludeCharacters.Add(node.InnerText);
            }
            XmlNode RenameNode = xml.SelectSingleNode("History").SelectSingleNode("FindAndReplace");
            XmlNodeList FindAndReplaceNodes = RenameNode.ChildNodes;
            foreach (XmlNode node in FindAndReplaceNodes)
            {
                if (node.Name == "value")
                    m_FindAndReplaces.Add(node.InnerText);
            }
        }

        public void SaveHistory()
        {
            XmlNode DocumentCleanupNode = xml.SelectSingleNode("History").SelectSingleNode("VideoFileOrganization").SelectSingleNode("DocumentCleanup");
            XmlNode exetensionsNode = DocumentCleanupNode.SelectSingleNode("extensions");
            exetensionsNode.RemoveAll();
            foreach(string value in m_extensions)
            {
                XmlElement ele = xml.CreateElement("value");
                ele.InnerText = value;
                exetensionsNode.AppendChild(ele);
            }
            XmlNode exesNodes = DocumentCleanupNode.SelectSingleNode("Exes");
            exesNodes.RemoveAll();
            foreach (string value in m_Exes)
            {
                XmlElement ele = xml.CreateElement("value");
                ele.InnerText = value;
                exesNodes.AppendChild(ele);
            }
            XmlNode CharactersNodes = DocumentCleanupNode.SelectSingleNode("IncludeCharacters");
            CharactersNodes.RemoveAll();
            foreach (string value in m_IncludeCharacters)
            {
                XmlElement ele = xml.CreateElement("value");
                ele.InnerText = value;
                CharactersNodes.AppendChild(ele);
            }
            XmlNode RenameNode = xml.SelectSingleNode("History").SelectSingleNode("FindAndReplace");
            RenameNode.RemoveAll();
            foreach(string value in m_FindAndReplaces)
            {
                XmlElement ele = xml.CreateElement("value");
                ele.InnerText = value;
                RenameNode.AppendChild(ele);
            }
        }

        public string[] character_interception(string[] sorce, tReviseParam param)
        {
            string[] tartget = new string[sorce.Count()];
            if (param.subString[0] == "")
                return sorce;
            int i = 0;
            foreach (string str in sorce)
            {
                string subfolderName = Path.GetFileName(str);
                int index = subfolderName.IndexOf(param.subString[0]);
                if (index == -1)
                {
                    tartget[i] = str;
                }
                else
                {
                    string newSubfolderName;
                    string newSubfolderPath = sorce[i];
                    if (param.mode == eReviseMode.BEFORE_A_RESERVED_CHARACTER)
                    {
                        newSubfolderName = subfolderName.Substring(0, index);
                        newSubfolderPath = Path.Combine(Path.GetDirectoryName(str), newSubfolderName);

                    }
                    else
                    {
                        if (index < subfolderName.Length - 1)
                        {
                            newSubfolderName = subfolderName.Substring(index + 1);
                            newSubfolderPath = Path.Combine(Path.GetDirectoryName(str), newSubfolderName);
                        }
                    }
                    tartget[i] = newSubfolderPath;
                }
                i++;
            }
            return tartget;
        }

        public string[] character_reservation(string[] sorce, tReviseParam param)
        {
            string[] tartget = new string[sorce.Count()];
            for (int i = 0; i < sorce.Count(); i++)
            {
                string subfolderName = Path.GetFileName(sorce[i]);
                string newSubfolderName = "";
                switch (param.mode)
                {
                    case eReviseMode.RETAIN_CHINESE:
                        newSubfolderName = StringControl.KeepChinese(subfolderName);
                        break;
                    case eReviseMode.RETAIN_ENGLISH:
                        newSubfolderName = StringControl.KeepEnglish(subfolderName);
                        break;
                    case eReviseMode.RETAIN_NUMBER:
                        newSubfolderName = StringControl.KeepNumbers(subfolderName);
                        break;
                }
                if (newSubfolderName != "")
                    tartget[i] = Path.Combine(Path.GetDirectoryName(sorce[i]), newSubfolderName);
                else
                    tartget[i] = sorce[i];

            }
            return tartget;
        }

        public string[] RespaceName(string[] sorces, tReviseParam param)
        {
            string[] tartget = new string[sorces.Count()];
            string add = param.subString[0] + "/" + param.subString[1];
            if (!FindAndReplaces.Contains(add))
            {
                FindAndReplaces.Add(add);
            }
            for (int i = 0; i < sorces.Count(); i++)
            {
                string subfolderName = Path.GetFileName(sorces[i]);
                string newSubfolderName = "";
                switch (param.mode)
                {
                    case eReviseMode.REPLACE_THE_CHARACTERS:
                        newSubfolderName = StringControl.RespaceName(subfolderName, param.subString[0], param.subString[1]);
                        break;
                }
                if (newSubfolderName != "")
                    tartget[i] = Path.Combine(Path.GetDirectoryName(sorces[i]), newSubfolderName);
                else
                    tartget[i] = sorces[i];

            }
            return tartget;
        }

    }

}
